/**
 * MessageHandlerFactoryImpl.java<br>
 *
 *
 * @version 下午10:20:21
 */
package com.iwechat.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iwechat.emuns.ConstEmus;
import com.iwechat.mybatis.generator.model.TemplateMessage;
import com.iwechat.service.MessageHandler;
import com.iwechat.service.MessageHandlerFactory;
import com.iwechat.service.MsgTemplateFactory;
import com.iwechat.service.TempMsgPriorityQueue;
import com.iwechat.util.StringUtil;

/**
 * 消息处理工厂
 *
 *
 */
@Service
public class MessageHandlerFactoryImpl implements MessageHandlerFactory {
    private static final Logger logger = LogManager.getLogger();

    @Autowired
    MsgTemplateFactory          templateFac;

    @Resource(name = "message2DbHandler")
    MessageHandler              dbHandler;

    @Resource(name = "RedisPriorityQuenue")
    TempMsgPriorityQueue        queue;

    @PostConstruct
    public void init() {
        logger.info("### " + this + " init succeed!");
    }

    @Override
    public TemplateMessage prepare(JSONObject message) {
        TemplateMessage retMesg = new TemplateMessage();
        String tempFileId = message.getString(ConstEmus.templateId.value());
        try {
            int templateId = Integer.parseInt(tempFileId);
            String template = templateFac.getTemplate(templateId);
            int priority = templateFac.getPriority(templateId);
            if (template != null) {
                // ### replace values
                String openid = message.getString(ConstEmus.openid.value());
                template = template.replace(ConstEmus.$openid.value(), openid);
                // 按照顺序替换模板中的参数
                int k = message.getIntValue(ConstEmus.filedSize.value());
                JSONObject fields = message.getJSONObject(ConstEmus.fileds.value());
                String replaceV;
                for (int i = 0; i < k & fields != null; i++) {
                    replaceV = fields.getString(ConstEmus.filed_.value() + (i + 1));
                    template = template.replaceFirst(ConstEmus.$field.value(), replaceV);
                }
                // 若客户端提供的值不足将剩余参数替换为“ ”
                template = template.replaceAll(ConstEmus.$field.value(), " ");

                JSONObject tmClone = JSON.parseObject(template);
                String url = tmClone.getString(ConstEmus.url.value());

                // ### 模板消息链接后添加id参数：?openid=XXXXX&refid=YYYYY
                if (StringUtils.isNotEmpty(url)) {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put(ConstEmus.openid.value(), openid);
                    // 获取params
                    JSONObject paramsJson = message.getJSONObject(ConstEmus.params.value());
                    if (paramsJson != null) {
                        for (Entry<String, Object> e : paramsJson.entrySet()) {
                            params.put(e.getKey(), String.valueOf(e.getValue()));
                        }
                    }
                    url = StringUtil.addUtf8Parm2Url(url, params);
                    tmClone.put(ConstEmus.url.value(), url);
                }

                String tempmsg = tmClone.toJSONString();

                // 将替换好的消息设置到返回对象中
                retMesg.setTemplateId(tempFileId);
                retMesg.setPriority(priority);
                retMesg.setCreateTime(new Date());
                retMesg.setSendTime(null);
                retMesg.setClientId(message.getString(ConstEmus.clientId.value()));
                retMesg.setClientIp(message.getString(ConstEmus.clientIp.value()));
                retMesg.setJsoncontent(tempmsg);
                retMesg.setOpenidId(message.getString(ConstEmus.openid.value()));
                retMesg.setSequence(message.getString(ConstEmus.sequence.value()));
                retMesg.setSessionId(message.getString(ConstEmus.sessionId.value()));
                retMesg.setStartTime(message.getString(ConstEmus.startTime.value()));
                retMesg.setStopTime(message.getString(ConstEmus.stopTime.value()));

                logger.debug(retMesg.toString());

            } else {
                logger.error("tempFileId: " + tempFileId + ",no config json template file!");
                retMesg = null;
            }
        } catch (Exception e) {
            logger.error(e, e);
            retMesg = null;
        }
        return retMesg;
    }

    @Override
    public int doHandle(TemplateMessage message) {
        int code = 0;
        try {
            code = dbHandler.handle(message);
        } catch (Exception e) {
            logger.error(e, e);
            code = -1001;
        }
        // 实时消息需要继续处理
        if (code == 100) {
            message.setCreateTime(new Date());
            queue.offer(message);
        }
        code = code > 0 ? 0 : code;
        return code;
    }

}
